﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WikeSoft.WorkFlowEngine.Entities;
using WikeSoft.WorkFlowEngine.Models;

namespace WikeSoft.WorkFlowEngine.Tools
{
    public class DrawingCurve
    {
       
        //剪切的起点
        private int cutX = -50;
        private int cutY = -50;

        //剪切的大小
        private int cutWidth = 1000;

        private int cutHeight = 1000;


        internal Bitmap DrawingFlow(List<TaskDefinition> nodes, List<TaskLink> nodelLinks)
        {
            CalCutArea(nodes, nodelLinks);

            

            Color penColor =Color.CadetBlue;
            float penSize = 2f;
            Font font = new Font("宋体", 10);
            Font linkFont = new Font("宋体", 8);
            Pen pen = new Pen(penColor, penSize);
            pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;

            Pen allowpen = new Pen(penColor, penSize);
            System.Drawing.Drawing2D.AdjustableArrowCap lineCap =
                new System.Drawing.Drawing2D.AdjustableArrowCap(3, 3, true);
            allowpen.CustomEndCap = lineCap;


            Bitmap img = new Bitmap(cutWidth, cutHeight); //图片大小
            Graphics g = Graphics.FromImage(img);
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.Clear(Color.White);


            if (nodes != null)
            {
                foreach (var node in nodes)
                {
                    g.DrawRectangle(pen, node.LeftX, node.TopX - 3, node.Width, node.Height);
                    g.DrawString(node.NodeDefName, font, Brushes.Brown, new Point(node.LeftX + 2, node.TopX + 2));

                }
                foreach (var nodelink in nodelLinks)
                {
                    if (!String.IsNullOrEmpty(nodelink.LinkName))
                    {
                        g.DrawString(nodelink.LinkName, linkFont, Brushes.Black, new Point((int)nodelink.LinkNameLeft, (int)nodelink.LinkNameTop));
                    }

                    var linkLeft = nodelink.StartLeft >= nodelink.EndLeft ? nodelink.EndLeft : nodelink.StartLeft;
                    var linkTop = nodelink.StartTop >= nodelink.EndTop ? nodelink.EndTop : nodelink.StartTop;

                    String path = nodelink.Path;
                    if (path.StartsWith("M"))//去掉第一个M
                    {
                        path = path.Substring(1);
                    }
                    String[] array = path.Split(new[] { 'M' });

                    for (int i = 0; i < array.Length; i++)
                    {
                        if (array[i].Contains("L")) //如果是直线
                        {
                            String[] subpath = array[i].Split('L');
                            String[] start = subpath[0].Trim().Split(' ');
                            String[] end = subpath[1].Trim().Split(' ');

                            int startPointX = (int)(linkLeft + Convert.ToDouble(start[0]));
                            int startPointY = (int)(linkTop + Convert.ToDouble(start[1]));

                            int endPointX = (int)(linkLeft + Convert.ToDouble(end[0]));
                            int endPointY = (int)(linkTop + Convert.ToDouble(end[1]));



                            Point startPoint = new Point(startPointX, startPointY);
                            Point endPoint = new Point(endPointX, endPointY);

                            if (i == array.Length - 1) //最后一个线加箭头
                            {
                                g.DrawLine(allowpen, startPoint, endPoint);
                            }
                            else
                            {
                                g.DrawLine(pen, startPoint, endPoint);
                            }
                        }
                    }


                }

                //计算剪切的长和宽
                CalCutArea(nodes, nodelLinks);

                //计算剪切点
                CalCutPoint(nodes, nodelLinks);
            }

            return img;
            //return Cut(img, cutX - 3, cutY - 5, cutWidth + 7, cutHeight + 7);
        }

        internal Bitmap DrawingFlow(List<TaskDefinition> nodes, List<TaskLink> nodelLinks,TaskDefinition currentNodeDef)
        {
            CalCutArea(nodes, nodelLinks);
            Color penColor = Color.CadetBlue;
            float penSize = 2f;
            Font font = new Font("宋体", 10);
            Font linkFont = new Font("宋体", 8);
            Pen pen = new Pen(penColor, penSize);
            pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
            Pen currenNodepen = new Pen(Color.Red, penSize);
            currenNodepen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
            Pen allowpen = new Pen(penColor, penSize);
            System.Drawing.Drawing2D.AdjustableArrowCap lineCap =
                new System.Drawing.Drawing2D.AdjustableArrowCap(3, 3, true);
            allowpen.CustomEndCap = lineCap;


            Bitmap img = new Bitmap(cutWidth, cutHeight); //图片大小
            //img.MakeTransparent();
            Graphics g = Graphics.FromImage(img);
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.Clear(Color.White);

            foreach (var node in nodes)
            {
                if (currentNodeDef!=null && node.Id == currentNodeDef.Id)
                {
                    g.DrawRectangle(currenNodepen, node.LeftX, node.TopX - 3, node.Width, node.Height);
                    g.DrawString(node.NodeDefName, font, Brushes.Brown, new Point(node.LeftX + 2, node.TopX + 2));
                }
                else
                {
                    g.DrawRectangle(pen, node.LeftX, node.TopX - 3, node.Width, node.Height);
                    g.DrawString(node.NodeDefName, font, Brushes.CadetBlue, new Point(node.LeftX + 2, node.TopX + 2));
                }
               
              

            }
            foreach (var nodelink in nodelLinks)
            {
                if (!String.IsNullOrEmpty(nodelink.LinkName))
                {
                    g.DrawString(nodelink.LinkName, linkFont, Brushes.Black, new Point((int)nodelink.LinkNameLeft, (int)nodelink.LinkNameTop));
                }

                var linkLeft = nodelink.StartLeft >= nodelink.EndLeft ? nodelink.EndLeft : nodelink.StartLeft;
                var linkTop = nodelink.StartTop >= nodelink.EndTop ? nodelink.EndTop : nodelink.StartTop;

                String path = nodelink.Path;
                if (path.StartsWith("M"))//去掉第一个M
                {
                    path = path.Substring(1);
                }
                String[] array = path.Split(new[] { 'M' });

                for (int i = 0; i < array.Length; i++)
                {
                    if (array[i].Contains("L")) //如果是直线
                    {
                        String[] subpath = array[i].Split('L');
                        String[] start = subpath[0].Trim().Split(' ');
                        String[] end = subpath[1].Trim().Split(' ');

                        int startPointX = (int)(linkLeft + Convert.ToDouble(start[0]));
                        int startPointY = (int)(linkTop + Convert.ToDouble(start[1]));

                        int endPointX = (int)(linkLeft + Convert.ToDouble(end[0]));
                        int endPointY = (int)(linkTop + Convert.ToDouble(end[1]));



                        Point startPoint = new Point(startPointX, startPointY);
                        Point endPoint = new Point(endPointX, endPointY);

                        if (i == array.Length - 1) //最后一个线加箭头
                        {
                            g.DrawLine(allowpen, startPoint, endPoint);
                        }
                        else
                        {
                            g.DrawLine(pen, startPoint, endPoint);
                        }
                    }
                }


            }

            //计算剪切的长和宽
            CalCutArea(nodes, nodelLinks);

            //计算剪切点
            CalCutPoint(nodes, nodelLinks);

            return img;

            //return Cut(img, cutX - 3, cutY - 5, cutWidth + 7, cutHeight + 7);
        }

        private void CalCutArea(List<TaskDefinition> nodes, List<TaskLink> nodelLinks)
        {
            int pointX = 0;

            int pointY = 0;
            foreach (var node in nodes)
            {
                int currentX = node.LeftX + node.Width;
                if (currentX > pointX)
                {
                    pointX = currentX;
                }
                int currentY = node.TopX + node.Height;
                if (currentY > pointY)
                {
                    pointY = currentY;
                }
            }
            cutWidth = pointX - cutX;
            cutHeight = pointY - cutY;

        

            //计算高度
            foreach (var nodelink in nodelLinks)
            {
                var linkLeft = nodelink.StartLeft >= nodelink.EndLeft ? nodelink.EndLeft : nodelink.StartLeft;
                var linkTop = nodelink.StartTop >= nodelink.EndTop ? nodelink.EndTop : nodelink.StartTop;

                String path = nodelink.Path;
                if (path.StartsWith("M"))//去掉第一个M
                {
                    path = path.Substring(1);
                }
                String[] array = path.Split(new[] { 'M' });

                for (int i = 0; i < array.Length; i++)
                {
                    if (array[i].Contains("L")) //如果是直线
                    {
                        String[] subpath = array[i].Split('L');
                        String[] start = subpath[0].Trim().Split(' ');
                        String[] end = subpath[1].Trim().Split(' ');

                        int startPointX = (int)(linkLeft + Convert.ToDouble(start[0]));
                        int startPointY = (int)(linkTop + Convert.ToDouble(start[1]));

                        int endPointX = (int)(linkLeft + Convert.ToDouble(end[0]));
                        int endPointY = (int)(linkTop + Convert.ToDouble(end[1]));
                        if (startPointX > cutX + cutWidth)
                        {

                            cutWidth = startPointX - cutX;
                        }
                        if (startPointY > cutY + cutHeight)
                        {
                            cutHeight = startPointY - cutY;
                        }

                        if (endPointX > cutX + cutWidth)
                        {
                            cutWidth = endPointX - cutX;
                        }
                        if (endPointY > cutY + cutHeight)
                        {
                            cutHeight = endPointY - cutY;
                        }
                    }
                }
            }

        }


        private void CalCutPoint(List<TaskDefinition> nodes, List<TaskLink> nodelLinks)
        {

            foreach (var node in nodes)
            {
                if (node.LeftX < cutX)
                {
                    cutX = node.LeftX;
                }
                if (node.TopX < cutY)
                {
                    cutY = node.TopX;
                }

            }
            //计算剪切的起点和终点
            foreach (var nodelink in nodelLinks)
            {


                var linkLeft = nodelink.StartLeft >= nodelink.EndLeft ? nodelink.EndLeft : nodelink.StartLeft;
                var linkTop = nodelink.StartTop >= nodelink.EndTop ? nodelink.EndTop : nodelink.StartTop;

                String path = nodelink.Path;
                if (path.StartsWith("M"))//去掉第一个M
                {
                    path = path.Substring(1);
                }
                String[] array = path.Split(new[] { 'M' });

                for (int i = 0; i < array.Length; i++)
                {
                    if (array[i].Contains("L")) //如果是直线
                    {
                        String[] subpath = array[i].Split('L');
                        String[] start = subpath[0].Trim().Split(' ');
                        String[] end = subpath[1].Trim().Split(' ');

                        int startPointX = (int)(linkLeft + Convert.ToDouble(start[0]));
                        int startPointY = (int)(linkTop + Convert.ToDouble(start[1]));

                        int endPointX = (int)(linkLeft + Convert.ToDouble(end[0]));
                        int endPointY = (int)(linkTop + Convert.ToDouble(end[1]));

                        if (startPointX < cutX)
                        {
                            cutWidth = cutWidth + cutX - startPointX;
                            cutX = startPointX;
                        }
                        if (endPointX < cutX)
                        {
                            cutWidth = cutWidth + cutX - endPointX;
                            cutX = endPointX;
                        }

                        if (startPointX < cutY)
                        {
                            cutHeight += cutY - startPointX;
                            cutY = startPointY;
                        }

                        if (endPointY < cutY)
                        {
                            cutHeight += cutY - endPointY;
                            cutY = endPointY;
                        }
                    }
                }
            }
        }

        public static Bitmap Cut(Bitmap b, int StartX, int StartY, int iWidth, int iHeight)
        {
            if (b == null)
            {
                return null;
            }
            int w = b.Width;
            int h = b.Height;
            if (StartX >= w || StartY >= h)
            {
                return null;
            }
            if (StartX + iWidth > w)
            {
                iWidth = w - StartX;
            }
            if (StartY + iHeight > h)
            {
                iHeight = h - StartY;
            }
            try
            {
                Bitmap bmpOut = new Bitmap(iWidth, iHeight, PixelFormat.Format24bppRgb);
                Graphics g = Graphics.FromImage(bmpOut);
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                g.DrawImage(b, new Rectangle(0, 0, iWidth, iHeight), new Rectangle(StartX, StartY, iWidth, iHeight), GraphicsUnit.Pixel);
                g.Dispose();
                return bmpOut;
            }
            catch
            {
                return null;
            }
        }
    }
}
